home *** CD-ROM | disk | FTP | other *** search
/ Software 2000 / Software 2000 Volume 1 (Disc 1 of 2).iso / utilities / u118.dms / in.adf / mini-hello / README < prev   
Encoding:
Text File  |  1990-12-06  |  5.5 KB  |  135 lines

  1.   (c) 1990 S.Hawtin.
  2.   Permission is granted to copy this file provided
  3.    1) It is not used for commercial gain
  4.    2) This notice is included in all copies
  5.    3) Altered copies are marked as such
  6.  
  7.  
  8.   One complaint that is voiced about 'C' is that trivial programs are too 
  9. large.  This opinion is usually held by those who have "played with" 'C' 
  10. and only every produced trivial programs, in this directory I explain how 
  11. to make smaller 'C' programs, and what you lose by doing so.
  12.  
  13.   Before I can describe how to create small programs I must explain why 
  14. the simplest 'C' program, which is
  15.  
  16.     main()
  17.        {
  18.         }
  19.  
  20. takes so much space.
  21.  
  22.   The first thing to note is that every 'C' program consists of three 
  23. parts, the startup code, the programmers routines, and the 'C' library.  
  24. The startup code is a standard set of routines that are called when every 
  25. 'C' program starts, these routines set up things so that the 'C' library 
  26. will work and calls the users main() routine in a standard way.  The 'C' 
  27. library is a set of routines that the user may want to call, these range 
  28. from the very well used routines such as printf() to the extremely obscure 
  29. routines such as strpbrk().
  30.  
  31.   The 'C' library will only add code if one of the other two parts 
  32. requires it, so for example the strstr() function is added to the 
  33. application only if it is called from the startup, which it isn't, or the 
  34. users code.  For some routines the situation is more complicated, the 
  35. fputs() routine, for example, calls the fputc() routine, so if the startup 
  36. calls fputs() then both fputs() and fputc() are linked into the final 
  37. executable program from the 'C' library.
  38.  
  39.   The normal 'C' startup code calls some routines in the 'C' library, on 
  40. real applications this makes little difference to the size of the final 
  41. code, because the users code probably calls all the routines that the 
  42. startup uses anyway.  On trivial applications the chances are that the 
  43. routines the application calls are different from those that the startup 
  44. uses.  For example the startup uses fputs() if the application calls 
  45. printf() then the final code must include both routines, even though they 
  46. do almost the same job, so the final program will be larger.  So if the 
  47. hello world program is written as
  48.  
  49.     #include <stdio.h>
  50.  
  51.     main()
  52.        {fputs("Hello world\a\n",stdout);
  53.         }
  54.  
  55. then the executable code will be smaller, the routines that the startup 
  56. uses are
  57.  
  58.     atexit()        CloseLibrary()        exit()
  59.     fclose()        fflush()           fputc()
  60.     fputs()        free()            ltoa()
  61.     malloc()        OpenLibrary()        strncpy()
  62.     _exit()        _main()
  63.  
  64. so if you stick to this set you will reduce the size of your program.
  65.  
  66.   This is all to the good, however since the empty program is a few 
  67. kilobytes long this is not the ultimate answer, we must reduce the size of 
  68. the startup code.
  69.  
  70.   The startup code is the same for the vast majority of 'C' programs, the 
  71. programmer has to work hard to use a different startup routine.  This 
  72. means that the startup must initialise the data structures for all the 
  73. possible library routines that the program can call, for example the 
  74. malloc() family of routines maintain a list of allocated memory chunks, so 
  75. that they can be freed when the program exits, this list must be 
  76. initialised just in case the program is going to call malloc().  There are 
  77. quite a few lists and data structures that must be set up.
  78.  
  79.   The startup code is split over a number of routines, the "crt0.asm" file 
  80. contains most of the low level routines, these call the higher level 
  81. routines.  The low level routines initialise the malloc() lists, the 
  82. floating point support, the Amiga library support, the low level file 
  83. handling, starting from the Workbench and the low level _exit() routine.  
  84. The high level routines deal with the "FILE" structures, the exit() and 
  85. atexit() routines, and the command line processing.  Most of the space in 
  86. the high level routines deals with the command line processing, this is an 
  87. area that is often neglected, for example the command
  88.  
  89.     example "Arg one in quotes" two three
  90.  
  91. has three arguments.  Other languages, and even some 'C' compilers, will 
  92. treat this as six arguments.
  93.  
  94.   So the reason why the empty program is so large is that it contains 
  95. support for all the obscure 'C' routines you could have used, even if you 
  96. don't.  So the ultimate way to reduce the final size of your 'C' code is 
  97. to take out the support for the routines you are not going to use, start 
  98. with the "crt0.asm" file, and take out the calls that initialise the 
  99. structures you don't want.  This is what I have done in this directory, I 
  100. have created "crt1.asm" a startup that sets up very little, and calls the 
  101. routine _main().
  102.  
  103.   Of course if you want to use this trick to reduce the size of a program 
  104. you would take the following steps,
  105.  
  106.     1)  Get the program working with the normal startup.
  107.     2)  Change the main() routine from
  108.  
  109.             main(argc,argv)
  110.                 int argc;
  111.                 char **argv;
  112.                {
  113.                 .
  114.                 .
  115.                 }
  116.  
  117.         remove all the FILE references and change the function to
  118.  
  119.             extern long _cmndlen;
  120.             extern char *_cmndstr;
  121.             extern long _fromWB;
  122.  
  123.             _main()
  124.                {
  125.                 .
  126.                 .
  127.                 }
  128.  
  129.     3)  Get a local copy of "crt1.asm" and remove the bits you don't need.
  130.  
  131.     4)  Edit your Makefile to use the local "crt1.o" rather than "clibs:crt0.o".
  132.  
  133. Once you have done all this you will learn a great deal about the guru, it 
  134. really is simpler to live with the larger programs.
  135.